關鍵詞:GNU/Linux;串口通訊;并口I/O操作;usb存儲設備 中圖分類號:Tll 文獻標識碼:A The Applications of the General I/O in the GNU/Linux LIU Yang,ZHOU Chun-jie (Department of Control Science and Engineering, HuaZhong University of Science & Technology, WuHan 430074, China) Abstract: This paper introduced the detailed operations of three kinds of the general I/O in the GNU/ Linux on the x86 platform, which are the serial communication, the standard parallel ports and the usb mass- storage devices. Key words: GNLT/Linux; serial communication; parallel ports; usb mass - storage 1 引言 GNU/Linux是一個開放源代碼,通用的,符合 POSIX(IEEE Standard Portable Operating System Interface for Computer Environment)標準的操作系統。其健壯、穩定、功能強大的特點,在服務器領域與嵌入式設備上極為流行。在通常的PCx86體系下,常用的標準I/O操作有三種:串口,并口、USB口與網口。GNU/Linux作為一種類UNIX系統繼承了UNIX的傳統,將所有I/0操作都作為一種特殊的文件操作,程序員只需用通常的open()、 read()、write()、ioctl()、close()等函數就可以完成大部分的操作,大大減輕了軟件開發的難度,提高了開發的效率與可靠性,而這些I/O、的組合使用又基本可以滿足大部分系統的應用。本文以一個實際系統為例,說明了基于PCx86體系下的串口、并口與USB口操作,網口由于其本身的特殊性,在本文就不作為一般的I/O介紹了。系統硬件示意圖如下,主控板為一塊586級的嵌入式主板PCM一5820,主頻為300Mhz、外擴128Mb內存、16M電子盤,主控板自帶兩個串口,一個標準25針并口,兩個USB口等接口;需要完成的功能有:與下層的一塊51為核心的按鍵顯示板通訊,讀入鍵值與刷新顯示;同時還需每10ms采集8路開關量輸入,通過一定的程序處理后輸出1路開關量;并不定期對采集的數據記錄做備份。實際系統正常工作時,實現長時間無人值守與可靠運行,本身要求有較高的穩定性。本文將從串口、并口、USB口三個方面介紹。
2 串口通訊實現 根據按鍵顯示板本身對通訊要求,具有一定的偶發性和要求有交互性,我們利用主控板上的串口選用RS232的通訊方式。由于在Linux下,串口一般作為一個終端接口,即tty接口,POSIX.1定義了一個查詢和操作終端的標準接口,該接口被稱作 termios,在系統的頭文件
中定義。 termios是一個數據結構和一系列操作這些數據結構的函數。 #include struct termios{ tcflag-t c-iflag;/*指明輸入方式的標志位*/ tcflag-t c-oflag;/*指明輸出方式的標志位*/ tcflag-t c-cflag;/*指明控制方式的標志位*/ tcflag-t c-lflag;/*指明局部方式的標志位*/ cc-t c-line;/*指明分行定義*/ cc-t C-CC[NCCS];/*指明用于控制的特殊字符*/ speed-t c-ispeed;/*指明輸入傳輸速度*/ speed-t c-ospeed;/*指明輸出傳輸速度*/ } 對終端訪問的控制函數如下:
這些函數一起共構成了通用的終端界面,提供對終端的有效控制操作,使得系統具有復雜的異步串口設備處理能力[4]。 RS232C只是一個物理層接口,為了保障數據傳輸的準確性與可靠性,須用戶自己保證數據傳輸正確,根據本系統通訊的特點:如果發生通訊,每次主機只會從按鍵顯示板接收到一幀包含按鍵信息的數據,而每次按鍵都是獨立事件;主控板向鍵盤顯示板發送一定數據更新顯示。按照此需求,定義通訊協議如下:接收時,每幀數據長度為5字節,發送時,每幀數據長度為12字節,波特率為9600B/s,1位停止位,8位數據位,不帶奇偶校驗。發送與接收的幀格式都是一樣的,幀首字節固定為0x55,第二個字節是本幀數據長度,最末兩字節為校驗和,其余為數據;緊跟著兩個相鄰數據包之間沒有關系,不需要幀序號,同時兩板之間距離很近,干擾源較少,因此誤碼率很低,用和校驗就可保證傳輸的誤碼率。具體設計實現如下:
具體設計時為了保證一定的系統響應速度,同時盡量減少主控板系統資源的使用,使用Linux下的信號驅動機制,使用SIGIO信號,當有下位機傳按鍵至主控板時,操作系統發出一個信號,用戶程序進入信號處理程序。初始化串口時,調用open()函數,打開設備文件ttyS0,發送和接收數據時就可以直接使用read()和write()函數,類似文件一樣使用串口。 3 并口操作實現 并口,有時也稱打印口,最初設計用于連接計算機和打印機。許多年后,其他很多設備也通過并口與計算機進行連接,例如掃描儀、可移動設備和復制保護設備等?,F代PC上,并口有8根雙向數據線、四根雙向控制線以及5根狀態輸入線,他們通過一個DB一25凹口連接器供外部進行訪問。從并口發明之初到現在,共發展出4種類型,實際系統中,主板的bios可以設置并口類型,本系統將主控板設為標準并口類型(SPP)。 在GNU/Linux下,一般對于PC并口進行數據采集和控制有3種方法。第一種方法使用端口 I/O,簡單、操作性強,并且可以清楚說明編寫設備驅動程序開發所必需的底層硬件控制過程。第二種方法使用Linux并口設備驅動程序ppdev來控制并口。這種方法與通過使用設備驅動程序及 ioctl系統調用進行串口控制的方法相似。第三種方法創建自己訂制的并口驅動程序,這個并口驅動 程序使用/proc目錄。本系統要求達到每10ms采集一次開關量的要求,并根據運算結果,輸出一個開關量;可以利用并口中的pin2 - pin9數據口,一次將8個開關量全部采集,并通過程序判斷,輸出結果至pin1口。采用第一種方法就能滿足本系統的要求,因此具體實現如下: 在Linux中有一個用于輸入的命令inb(ad— dress)和一個用于輸出的命令outb(value,address)。 C語言的宏擴展實現了這兩個函數,而且不涉及任何函數庫,但使用這兩個函數需要一些額外的函數,函數ioperm()從內核中申請和釋放端口訪問權[7]。 向并口寫入一個字節代碼如下: if(ioperm(0x378,3,1) ) exit (1); outb ( LP-DATA, 0x378); if( ioperm(0X378,3,0 )) exit(1); 從并口讀人一個字節代碼如下: if(ioperm(Ox378,3,1)) exit(1); putc(inb(Ox378) ); if( ioperm(OX378,3,0)) exit (1); 只要在上述代碼增加少量代碼就可以作為一個完整的代碼。這種方法也有缺點,只有root用戶才能調用ioperm函數,這會影響沒有root權限的用戶使用該程序,而且如果用戶想使用除了數據位以外的控制位作為輸出或輸入信號鎖存輸出值時,則會帶來很大困難,另外,這樣的程序實現可重入,將會面臨很大難度。但在本系統中,由于正式系統不存在用戶登錄的問題,同時,并口只會被本進程使用,不存在重入的問題。 為了保證每10ms的讀一次并口,利用Linux系統中的信號機制,使用settimer()函數,每10ms產生一次SIGALRM信號,在這個信號的中斷函數里,采集一次開關量。保證了系統的實時性T4。 4 USB口用于數據備份具體實現 由于系統是24小時不停機的長時間運行,本身采集的數據量是比較大的,可是主控板本身的存儲空間很小,而現場不具備安裝網線的條件,所以需要考慮一種盡可能不增加硬件投資,又可以獲得高可靠性,同時考慮到數據量比較大,對傳輸速率要求比較高,一般的串口已經無法滿足要求,因此,采用USB的傳輸方案,利用u盤將現場的數據暫存,回到控制中心,再將數據倒入數據庫。另外,為了減少工作人員的工作量,利用Linux本身特有的 RAMDISK功能,將內存中分出70Mb作為暫存區,并將這部分作為系統的另一個分區,在系統啟動的時候,直接掛載到系統中。 對于2.4.x的內核來說,USB存儲設備驅動已經集成在內核里,但驅動程序只與Linux SCSI層交互。這意味著,在配置內核時,除了配置USB選項之外,還需要配置某些SCSI選項,選擇支持合適的文件系統。在內核已支持USB存儲設備的情況下,當USB設備接人系統的USB口后,直接使用外部命令mount和umount的命令就可以將 USB存儲設備掛載到系統和解除掛載了。用cp等外部命令就可以將需要備份的數據從暫存區移動至USB存儲設備中。在程序中,使用system函數可以完成對外部命令程序的調用。具體實現過程如下: 1、檢測外部USB設備是否掛載到系統上,檢查/proc/bus/usb/deviees文件,是否已經正確掛載上去,其次,根據/proc/scsi/目錄中設備文件的內容,生成mount命令的第一個參數;2、用system函數調用mount命令,將USB存儲設備掛載至文件系統節點/mnt下; 3、用system函數調用cp命令,將ramdisk中的內容拷貝到該目錄下; 4、用system函數調用umount命令,將移動介質卸載調。 5 總結 系統已經在現場運行了半年,從運行的效果來看,串口通訊采用IO信號驅動的方式完全可以適應其偶發性與一定的實時性,并口經常作為IO數據的采集與輸出,采用定時掃描,而linux2.4.26操作系統的最小時間間隙100Hz,保證了每10ms采集一次的要求;USB口由于其傳輸數據量大、可靠,作為大數據量與交換,在Linux下,所有u盤和活動硬盤必須遵循USB mass—storage協議才能穩定可靠運行。另外,針對不同的硬件應該制作不同的Linux內核,充分利用內核的模塊化,使用最少模塊的內核,完成盡可能多的任務?,F在系統已經開始實際運行,從運行的效果來開,所有的指標都可以滿足當初的設計要求,本身Linux系統的穩定性,完全可以實現無人值守。 參考文獻 [1] (美)Kurt Wall等.張輝譯.GNU/Linx編程指南(第二版)[M].北京:清華